package com.jamiexu.help.socket.server;

import com.jamiexu.help.socket.javabean.FileBean;
import com.jamiexu.help.socket.utils.OperationUtils;
import com.jamiexu.help.socket.utils.SocketUtils;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class Main extends Application {


    private ArrayList<FileBean> arrayList;

    private ServerSocket serverSocket;


    @FXML
    private TextField directory_path;

    @FXML
    private TextField port;

    File file;

    @Override
    public void start(Stage primaryStage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("文件发送端");
        primaryStage.setScene(new Scene(root, 459, 97));
        primaryStage.setMaxWidth(459);
        primaryStage.setMaxHeight(97);
        primaryStage.setMinWidth(459);
        primaryStage.setMinHeight(97);
        primaryStage.show();
    }

    @FXML
    public void startServer() {
        String port = this.port.getText();
        String path = this.directory_path.getText();
        if (path.equals("") || port.equals(""))
            return;

        if (port.matches("[^\\d]+"))
            return;


        file = new File(path);
        if (!file.isDirectory()) {
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setTitle("错误：");
            alert.setContentText("请输入文件夹路径");
            alert.show();
            return;
        }


        new Thread(() -> {
            try {
                this.serverSocket = new ServerSocket(Integer.parseInt(port));
                Socket socket = this.serverSocket.accept();
                while (true) {
                    byte[] data = SocketUtils.getData(socket);
                    if (data == null)
                        continue;
                    Object[] block = SocketUtils.getBlock(data);
                    processOp(socket, block);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();


    }

    public void processOp(Socket socket, Object[] block) {

        String op = (String) block[0];
        String head = (String) block[1];
        byte[] data = (byte[]) block[2];
        int ver = (int) block[3];
        System.out.println("客户端：" + op);

        if (op.equals(OperationUtils.OP_CONNECT_CONNECT)) {
            SocketUtils.sendOPData(socket, OperationUtils.OP_CONNECT_ACCEPT, OperationUtils.HEAD, null);
        } else if (op.equals(OperationUtils.OP_GET_FILE)) {
            refreshFile();
            SocketUtils.sendOPData(socket, OperationUtils.OP_FILE_LIST, OperationUtils.HEAD, this.arrayList);
        } else if (op.equals(OperationUtils.OP_DOWNLOAD_FILE)) {
            int num = Integer.parseInt(head.split("\r\n")[2]) - 1;
            String path = this.arrayList.get(num).getPath();
            System.out.println("文件路径：" + path);
            sendFile(socket, path);
        }

    }

    public void refreshFile() {
        this.arrayList = new ArrayList<>();
        File[] files = file.listFiles();
        for (int i = 0; i < files.length; i++) {
            this.arrayList.add(new FileBean(
                    i + 1,
                    files[i].getName(),
                    files[i].getAbsolutePath(),
                    files[i].length(),
                    (int) files[i].length() / 256));
        }
    }

    public void sendFile(Socket socket, String filePath) {
        SocketUtils.sendOPData(socket, OperationUtils.OP_FILE_START, OperationUtils.HEAD, null);
        int currentBlock = 1;
        try {
            FileInputStream fileInputStream = new FileInputStream(filePath);
            byte[] byt = new byte[256];
            while (fileInputStream.read(byt) != -1) {
                SocketUtils.sendFileData(socket, OperationUtils.OP_FILE, OperationUtils.HEAD + currentBlock, byt);
                currentBlock++;
            }
            fileInputStream.close();
            SocketUtils.sendOPData(socket, OperationUtils.OP_FILE_FINISH, OperationUtils.HEAD, null);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        launch(args);
    }
}
